package ch.bfh.ti.pixelator.send;

import java.io.IOException;

import android.app.Fragment;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.Toast;
import ch.bfh.ti.barcode.colorQrCode.ColorQrCodeGenerator;
import ch.bfh.ti.barcode.exception.EncodeException;
import ch.bfh.ti.barcode.io.CodeOutputStream;
import ch.bfh.ti.barcode.multiple.CodeEvent;
import ch.bfh.ti.barcode.multiple.CodeEventListener;
import ch.bfh.ti.barcode.multiple.MultipleCodeGenerator;
import ch.bfh.ti.pixelator.MainActivity;
import ch.bfh.ti.pixelator.R;

public class SendFragment extends Fragment {
	private SendPanel panel;
	private byte[] data;
	private String filename;
	private View sendSelect;
	private View sendCode;
	private MultipleCodeGenerator multipleCodeGenerator;
	private CodeOutputStream stream;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.fragment_main_send,
				container, false);
		panel = (SendPanel) rootView.findViewById(R.id.send_panel);
		sendSelect = rootView.findViewById(R.id.send_select);
		sendCode = rootView.findViewById(R.id.send_code);

		// Switch the views
		if (data != null) {
			update(data, filename);
		} else {
			sendCode.setVisibility(View.GONE);
			sendSelect.setVisibility(View.VISIBLE);
		}

		ImageButton imageButton = (ImageButton) rootView
				.findViewById(R.id.button_share_image);
		ImageButton fileButton = (ImageButton) rootView
				.findViewById(R.id.button_share_file);
		ImageButton resendButton = (ImageButton) rootView
				.findViewById(R.id.button_resend);
		ImageButton cancelButton = (ImageButton) rootView
				.findViewById(R.id.button_cancel);

		imageButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				// Open image pick intent
				Intent intent = new Intent(Intent.ACTION_PICK);
				intent.setType("image/*");
				startActivityForResult(intent, 100);
			}
		});

		fileButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				// Open file pick intent
				Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
				intent.setType("*/*");
				startActivityForResult(intent, 200);
			}
		});

		resendButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// Restart the barcode generation
				update(data, filename);
			}
		});

		cancelButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				stop();
			}
		});

		return rootView;
	}
	
	@Override
	public void onPause() {
		super.onPause();

		stop();
	}
	
	private void stop() {
		// Stop the barcode generation
		if (multipleCodeGenerator != null)
			multipleCodeGenerator.dispose();
		
		data = null;
		filename = null;
		
		// Switch the views
		sendCode.setVisibility(View.GONE);
		sendSelect.setVisibility(View.VISIBLE);
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent intent) {
		if (requestCode == 100)
			((MainActivity) getActivity()).handleSendImage(intent);
		else if (requestCode == 200)
			((MainActivity) getActivity()).handleBinaryData(intent);
	}

	public void update(String data) {
		update(data.getBytes(), "sent.txt");
	}

	public void update(byte[] data, String filename) {
		this.data = data;
		this.filename = filename;

		// Paint it later if not ready yet
		if (panel == null)
			return;

		// Dispose old MultipleCodeGenerator
		if (multipleCodeGenerator != null)
			multipleCodeGenerator.dispose();

		// Switch the views
		sendCode.setVisibility(View.VISIBLE);
		sendSelect.setVisibility(View.GONE);

		// Get the settings
		SharedPreferences pref = PreferenceManager
				.getDefaultSharedPreferences(getActivity());
		String frameSize = pref.getString("frameSizePref", "459");
		int firstFrameDuration = pref.getInt("firstFrameWaitPref", 2) * 1000;
		int frameDuration = (int) (1.0 / (float) pref.getInt("timePref", 200) * 60000.0);
		boolean errorCorrection = pref.getBoolean("errorCorrection", true);
		int errorCorrectionFrequency = pref.getInt("errorCorrectionFrequency",
				5);

		// Create the new barcode generation objects
		ColorQrCodeGenerator generator = new ColorQrCodeGenerator(
				Integer.parseInt(frameSize));
		try {
			if (errorCorrection)
				multipleCodeGenerator = new MultipleCodeGenerator(generator,
						frameDuration, firstFrameDuration, data.length,
						filename, errorCorrectionFrequency);
			else
				multipleCodeGenerator = new MultipleCodeGenerator(generator,
						frameDuration, firstFrameDuration, data.length,
						filename);
		} catch (EncodeException e1) {
			Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_LONG)
					.show();
		}

		if (multipleCodeGenerator == null)
			return;

		stream = new CodeOutputStream(multipleCodeGenerator);
		multipleCodeGenerator.addEventListener(new CodeEventListener() {
			@Override
			public void codeSent(CodeEvent event) {
				// Draw the barcode
				int[] result = event.getData();
				int size = (int) Math.sqrt(result.length);
				panel.setData(result, size, size);
			}
		});

		new Thread(new WriteThread()).start();
	}

	class WriteThread implements Runnable {
		public void run() {
			try {
				stream.write(data);
				stream.flush();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					stream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}